﻿import * as actionTypes from './actionTypes';
import { buildParent, expand, DEPARTMENTS, SECTIONS, TEACHERS } from '../common/immutable';
import permConverter from '../common/permConverter';
import { submitPerm } from '../svc/service-broker';

function selectTeacher(state, { department, section, teacher }) {
    var t = state.current && state.current.teacher;
    if (t === teacher) return state;
    return { ...state, current: { department, section, teacher } }
}
function checkPerm(state, { department, section, teacher, idx }) {
    const perm = permConverter.flipPerm(teacher.perm, idx);
    if (teacher.oldPerm === undefined) {
        teacher.oldPerm = Number.isInteger(teacher.perm) ? teacher.perm : 0;
    } else if (!permChanged(perm, teacher.oldPerm)) {
        delete teacher.oldPerm;
    }
    // new teacher must copy the oldPerm attribute as well
    const newTeacher = { ...teacher, perm };

    return updateStateAfterPermChanged(state, department, section, teacher, newTeacher);

    function permChanged(perm1, perm2) {
        /*     _____perm2_______
               | \ | u | 0 | n |
               | u | 0 | 0 | 1 |   
        perm1  | 0 | 0 | 0 | 1 |  
               | n | 1 | 1 | compare |
        */
        if (!perm1) perm1 = 0;
        if (!perm2) perm2 = 0;
        return perm1 !== perm2;
    }
}
function submitPermChange(state, { current: { department, section, teacher } }) {
    if (teacher.oldPerm === undefined) {
        console.error("submit with undefined old perm");
        return state;
    }
    // submit to server
    submitPerm(teacher);
    // update state
    delete teacher.oldPerm;
    const newTeacher = { ...teacher };
    return updateStateAfterPermChanged(state, department, section, teacher, newTeacher);
}
function clearOldPerm(state, { current: { department, section, teacher } }) {
    const perm = teacher.oldPerm;   // save old permission
    delete teacher.oldPerm;
    const newTeacher = { ...teacher, perm };    // rebuild teacher with old permission
    return updateStateAfterPermChanged(state, department, section, teacher, newTeacher);
}
function updateStateAfterPermChanged(state, department, section, teacher, currTeacher) {
    var currSec, currDep, college;

    if (!department) {  // change teachers under college
        college = buildParent(state.college, TEACHERS, teacher, currTeacher);
        return { ...state, college, current: { teacher: currTeacher } }
    }

    if (!section) {     // change teachers under departmnt
        currDep = buildParent(department, TEACHERS, teacher, currTeacher);
        college = buildParent(state.college, DEPARTMENTS, department, currDep);
        return { ...state, college, current: { department: currDep, teacher: currTeacher } }
    }

    // change teachers under section
    currSec = buildParent(section, TEACHERS, teacher, currTeacher);
    currDep = buildParent(department, SECTIONS, section, currSec);
    college = buildParent(state.college, DEPARTMENTS, department, currDep);
    return { ...state, college, current: { department: currDep, section: currSec, teacher: currTeacher } };
}

export default function authorize(state = {}, action) {
    switch (action.type) {
        case actionTypes.EXPAND_AUTH:
            return {
                ...state,
                college: expand(state.college, action.department, action.section)
            };
        case actionTypes.SELECT_TEACHER:
            return selectTeacher(state, action);
        case actionTypes.CHECK_PERM:
            return checkPerm(state, action);
        case actionTypes.SUBMIT:
            return submitPermChange(state, action);
        case actionTypes.CANCEL:
            return clearOldPerm(state, action);
        default:
            return state;
    }
}